package com.chuanke.ckfamily.action.user;

import java.sql.Timestamp;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import com.chuanke.ckfamily.action.BaseController;
import com.chuanke.ckfamily.action.base.Response;
import com.chuanke.ckfamily.dao.social.model.FamilyMember;
import com.chuanke.ckfamily.dao.user.model.User;
import com.chuanke.ckfamily.service.base.FailCode;
import com.chuanke.ckfamily.service.common.RSAService;
import com.chuanke.ckfamily.service.common.TokenService;
import com.chuanke.ckfamily.service.common.model.UserToken;
import com.chuanke.ckfamily.service.exception.CFException;
import com.chuanke.ckfamily.service.social.FamilyMemberService;
import com.chuanke.ckfamily.service.social.FamilyService;
import com.chuanke.ckfamily.service.social.SpecialRelationService;
import com.chuanke.ckfamily.service.user.UserRelationService;
import com.chuanke.ckfamily.service.user.UserService;
import com.weijie.core.util.StringUtils;

@Api(value = "UserController | 用户相关api", tags = "用户", description = "用户相关接口")
@Controller
@RequestMapping("/api/user")
public class UserController extends BaseController {

    private static final Logger logger = LoggerFactory.getLogger(UserController.class);

    @Autowired
    private UserService userService;

    @Autowired
    private UserRelationService userRelationService;

    @Autowired
    private SpecialRelationService specialRelationService;

    @Autowired
    private FamilyService familyService;

    @Autowired
    private FamilyMemberService familyMemberService;

    @Autowired
    private TokenService tokenService;

    @Autowired
    private RSAService rsaService;

    /**
     * <h1>用户登录获取token接口</h1>
     *
     * @param uid 用户id
     * @return data为token
     */
    @ApiOperation(value = "/login_token", notes = "用户返回token")
    @ApiImplicitParam(name = "uid", value = "用户id", paramType = "form", required = true)
    @ResponseBody
    @RequestMapping("/login_token")
    public Response getLoginToken(@RequestParam("uid") Long uid) {
        try {
            logger.debug("login token = {}", uid);
            User user = userService.login(uid);
            user.setLogin_time(new Timestamp(System.currentTimeMillis()));
            userService.update(user);

            logger.debug("create token for user={}", user.getId());
            String token = tokenService.createToken(user, true, true);
            return new Response(token);

        } catch (CFException e) {
            return new Response(e);

        } catch (Exception e) {
            e.printStackTrace();
            return new Response(FailCode.APP, e.getMessage());

        }
    }

    /**
     * <h1>App登录接口</h1>
     *
     * @param token
     * @return
     */
    @ApiOperation(value = "登录接口alogin", notes = "app自动登录调用")
    @ApiImplicitParam(name = "token", value = "用户koken", paramType = "form", required = true)
    @RequestMapping("/alogin")
    @ResponseBody
    public Response autoLogin(@RequestParam("token") String token) {
        logger.debug("begin auto login");
        String destToken = rsaService.decrypt(token);
        if (StringUtils.isEmpty(destToken)) {
            return new Response(FailCode.RELOGIN);
        }

        try {
            UserToken userToken = tokenService.getUserToken(destToken);
            if (userToken == null) {
                logger.debug("token is null token={}", destToken);
                return new Response(FailCode.RELOGIN);
            }

            User user = userService.login(userToken.getId());
            logger.debug("登录===============>uid={}", userToken.getId());
            if (user == null || !user.getToken().equals(userToken.getToken())) {
                logger.debug("token is not equals send token={}, userTOken = {}", destToken, user.getToken());
                return new Response(FailCode.RELOGIN);
            }

            FamilyMember member = familyMemberService.findByUserId(user.getId());
            logger.info("member = {} ", member);
            user.setShield(member != null && member.getShield() != null ? member.getShield() : 0);

            Map<String, Object> result = new HashMap<>(2);
            result.put("user", user);
            result.put("token", tokenService.createToken(userToken, true));

            logger.debug("auto login end ={}", result);
            return new Response(result);

        } catch (CFException e) {
            return new Response(e);

        } catch (Exception e) {
            e.printStackTrace();
            return new Response(FailCode.APP, e.getMessage());

        }
    }

    /**
     * 查询用户
     *
     * @param request
     * @param phone
     * @return
     */
    @ApiOperation(value = "查询用户", notes = "使用电话号码查询用户")
    @ApiImplicitParam(name = "phone", value = "用户电话号码", paramType = "form", required = true)
    @RequestMapping("/search")
    @ResponseBody
    public Response searchUser(HttpServletRequest request,
                               @RequestParam("phone") String phone) {
        try {
            Long uid = getUidByToken(request);
            List<User> userList = userService.findByPhone(uid, phone);
            return new Response(userList);

        } catch (CFException e) {
            return new Response(e);

        } catch (Exception e) {
            e.printStackTrace();
            return new Response(FailCode.APP, e.getMessage());

        }
    }

    /**
     * <h1>获取用户详情</h1>
     * api/user/user_info
     * 备注：
     * tuserNo为空查询自己用户详情
     * tuserNo不为空查询其他用户详情
     *
     * @param request
     * @return data 为用户信息
     */
    @ApiOperation(value = "获取用户详情", notes = "用户的详情信息")
    @ApiImplicitParam(name = "tuserNo", value = "用户的no", paramType = "form", required = true)
    @RequestMapping("/user_info")
    @ResponseBody
    public Response user_info(HttpServletRequest request, @RequestParam(value = "tuserNo", required = false) String tuserNo) {
        try {
            Long uid = getUidByToken(request);
            Map<String, Object> result = userService.getUserInfo(uid, tuserNo);
            logger.debug("user_info==========>uid={},tuserNo={},result={}", uid, tuserNo, result);
            return new Response(result);

        } catch (CFException e) {
            return new Response(e);

        } catch (Exception e) {
            e.printStackTrace();
            return new Response(FailCode.APP);
        }
    }


    /**
     * 查询自己或指定用户详细资料包含余额
     * 备注：此接口涉及调用创客获取余额,粉丝，所以耗时可能会较长
     * api/user/user_balance
     *
     * @param from    请求来源 1.新的好友页面
     * @param tuserNo 查看指定用户id
     * @return
     */
    @ApiOperation(value = "查询用户余额", notes = "查询自己或指定用户详细资料包含余额")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "tuserNo", value = "用户NO", required = true, paramType = "form", dataTypeClass = Long.class),
            @ApiImplicitParam(name = "from", value = "请求来源 1表示好友页面", required = true, paramType = "form", dataTypeClass = Integer.class)}
    )
    @RequestMapping("/user_balance")
    @ResponseBody
    public Response getUserBalance(HttpServletRequest request,
                                   @RequestParam(value = "tuserNo", required = false) String tuserNo,
                                   @RequestParam(value = "from", required = false) Integer from) {
        try {
            if (from == null) {
                from = 0;
            }
            Long uid = getUidByToken(request);
            Map<String, Object> result = userService.getUserBalance(uid, tuserNo, from);
            logger.debug("user_balance==========>uid={},tuserNo={},result={}", uid, tuserNo, result);
            return new Response(result);

        } catch (CFException e) {
            return new Response(e);

        } catch (Exception e) {
            e.printStackTrace();
            return new Response(FailCode.APP);

        }
    }


    /**
     * 家族成员资料
     * api/user/member_info
     *
     * @param tuserNo 返回
     *                族长是否可以踢出当前成员 is_kick
     *                最后活跃时间：user：active_timeStr
     *                入族时间：familyMember：create_timeStr
     *                是否被禁言。0：否 1：是
     * @return
     */
    @ApiOperation(value = "家族成员资料", notes = "查询家族成员资料")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "tuserNo", value = "用户NO", required = true, paramType = "form", dataTypeClass = Long.class),
            @ApiImplicitParam(name = "tid", value = "被踢出人id", required = true, paramType = "form", dataTypeClass = Integer.class)}
    )
    @RequestMapping("/member_info")
    @ResponseBody
    public Response member_info(HttpServletRequest request,
                                @RequestParam(value = "tuserNo", required = false) String tuserNo,
                                @RequestParam(value = "tid") String tid) {
        try {
            Long uid = getUidByToken(request);
            Map<String, Object> result = userService.getMemberInfo(uid, tuserNo, tid);
            logger.debug("member_info==========>uid={},tuserNo={},tid={},result={}", uid, tuserNo, tid, result);
            return new Response(result);

        } catch (CFException e) {
            return new Response(e);

        } catch (Exception e) {
            e.printStackTrace();
            return new Response(FailCode.APP);
        }
    }


    /**
     * 把指定用户加入到免打扰名单中
     * api/user/mute
     *
     * @param value   0:取消免打扰，1:加入免打扰
     * @param tuserId 用户id
     * @return
     */
    @ApiOperation(value = "用户免打扰", notes = "把指定用户加入到免打扰名单中")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "tuserId", value = "用户id", required = true, paramType = "form", dataTypeClass = Long.class),
            @ApiImplicitParam(name = "value", value = "0:取消免打扰，1:加入免打扰", required = true, paramType = "form", dataTypeClass = Integer.class)}
    )
    @RequestMapping("/mute")
    @ResponseBody
    public Response mute(HttpServletRequest request,
                         @RequestParam(value = "tuserId") Long tuserId,
                         @RequestParam(value = "value") Integer value) {
        try {
            Long uid = getUidByToken(request);
            specialRelationService.mute(uid, tuserId, value);
            return new Response(true);

        } catch (CFException e) {
            return new Response(e);

        } catch (Exception e) {
            e.printStackTrace();
            return new Response(FailCode.APP);

        }
    }

    /**
     * 把指定用户加入到黑名单中
     * api/user/black
     *
     * @param value   0:取消黑名单，1:加入黑名单
     * @param tuserId 用户id
     * @return
     */
    @ApiOperation(value = "用户拉黑", notes = "把指定用户加入到黑名单中")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "tuserId", value = "用户id", required = true, paramType = "form", dataTypeClass = Long.class),
            @ApiImplicitParam(name = "value", value = "0:取消黑名单，1:加入黑名单", required = true, paramType = "form", dataTypeClass = Integer.class)}
    )
    @RequestMapping("/black")
    @ResponseBody
    public Response black(HttpServletRequest request,
                          @RequestParam(value = "tuserId") Long tuserId,
                          @RequestParam(value = "value") Integer value) {
        try {
            Long uid = getUidByToken(request);
            Map<String, Object> result = specialRelationService.black(uid, tuserId, value);
            return new Response(result);

        } catch (CFException e) {
            return new Response(e);

        } catch (Exception e) {
            e.printStackTrace();
            return new Response(FailCode.APP);

        }
    }

    /**
     * 我的粉丝
     * 返回值新增 --> mySuper：我的上线
     * /api/user/my_fans
     *
     * @param date 日期
     * @param page 页码
     * @return 如果没有传日期则返回data:{"allfans":[user数组]}
     * 如果传入了日期则返回data:{"newfans":[user数组];"updatefans":[user数组]}
     */
    @ApiOperation(value = "我的粉丝", notes = "获取指定用户的粉丝")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "date", value = "日期", paramType = "form", dataTypeClass = String.class),
            @ApiImplicitParam(name = "page", value = "页码", paramType = "form", dataTypeClass = String.class)}
    )
    @ResponseBody
    @RequestMapping("/my_fans")
    public Response myFans(HttpServletRequest request,
                           @RequestParam(value = "date", required = false) String date,
                           @RequestParam(value = "page", required = false) String page) {

        try {
            Long uid = getUidByToken(request);
            logger.debug("my fans ==========>uid={},date={},page={}", uid, date, page);
            Map<String, Object> result = userService.getFans(uid, date, page);
            return new Response(result);

        } catch (CFException e) {
            return new Response(e);

        } catch (Exception e) {
            e.printStackTrace();
            return new Response(FailCode.APP, e.getMessage());
        }
    }

    /**
     * 修改好友，粉丝备注
     * api/user/remark_name
     *
     * @param tuserId    被修改备注 用户id
     * @param remarkName 备注
     * @return 修改的类型 {"type":类型}
     */
    @ApiOperation(value = "修改备注", notes = "修改好友，粉丝备注")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "tuserId", value = "被修改备注 用户id", required = true, paramType = "form", dataTypeClass = Long.class),
            @ApiImplicitParam(name = "remarkName", value = "备注", required = true, paramType = "form", dataTypeClass = String.class)}
    )
    @ResponseBody
    @RequestMapping("/remark_name")
    public Response updateRemarkName(HttpServletRequest request,
                                     @RequestParam("tuserId") Long tuserId,
                                     @RequestParam("remarkName") String remarkName) {
        try {
            Long uid = getUidByToken(request);
            Map<String, Object> result = userService.updateRemarkName(uid, tuserId, remarkName);
            return new Response(result);

        } catch (CFException e) {
            return new Response(e);

        } catch (Exception e) {
            e.printStackTrace();
            return new Response(FailCode.APP);

        }
    }

    /**
     * 首页搜索
     * /api/user/homeSearch
     *
     * @param keyword 搜索关键字
     * @return fansFamily ：粉丝家族
     * fans: 粉丝
     * friend：好友
     */
    @ApiOperation(value = "首页搜索", notes = "在首页根据关键字搜索")
    @ApiImplicitParam(name = "keyword", value = "搜索关键字", paramType = "form", required = true)
    @RequestMapping("/homeSearch")
    @ResponseBody
    public Response homeSearch(HttpServletRequest request,
                               @RequestParam(value = "keyword", required = false) String keyword) {
        try {
            Long uid = getUidByToken(request);
            Map<String, Object> result = userService.homeSearch(uid, keyword);

            logger.debug("homesearch=====>keyword={}, result={}", keyword, result);
            return new Response(result);
        } catch (CFException e) {
            return new Response(e);

        } catch (Exception e) {
            e.printStackTrace();
            return new Response(FailCode.APP, e.getMessage());

        }
    }
}